package com.cd.javacxy.module.web.service.impl;

import cn.hutool.core.util.StrUtil;
import com.cd.javacxy.common.model.entity.*;
import com.cd.javacxy.common.model.enums.DateTimePatternEnum;
import com.cd.javacxy.common.model.enums.TextLengthEnum;
import com.cd.javacxy.common.model.enums.VoteType;
import com.cd.javacxy.common.model.query.TopicVoteUserQuery;
import com.cd.javacxy.common.utils.DateUtil;
import com.cd.javacxy.exception.BussinessException;
import com.cd.javacxy.module.web.dao.CxyTopicVoteDao;
import com.cd.javacxy.module.web.dao.CxyTopicVoteDetailDao;
import com.cd.javacxy.module.web.dao.CxyTopicVoteUserDao;
import com.cd.javacxy.module.web.service.CxyTopicVoteService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.time.Instant;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * CxyTopicVote的服务接口的实现类
 *
 * @author yanghy
 */
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class CxyTopicVoteServiceImpl implements CxyTopicVoteService {

    private final CxyTopicVoteDao cxyTopicVoteDao;

    private final CxyTopicVoteDetailDao topicVoteDetailDao;

    private final CxyTopicVoteUserDao topicVoteUserDao;

    private final int MIN_VOTE_TITLE_LENGTH = 2;

    private final int MAX_VOTE_TITLE_LENGTH = 10;

    @Override
    public int addVote(CxyTopicVote topicVote, String[] voteTitle)
            throws BussinessException {
        if (voteTitle == null || voteTitle.length > MAX_VOTE_TITLE_LENGTH ||
                voteTitle.length < MIN_VOTE_TITLE_LENGTH ||
                StrUtil.isEmpty(topicVote.getEndDateString()) ||
                topicVote.getVoteType() == null
        ) {
            throw new BussinessException("参数错误");
        }
        for (String voteItem : voteTitle) {
            if (StrUtil.isEmpty(voteItem) || voteItem.length() > TextLengthEnum.TEXT_200_LENGTH.getLength()) {
                throw new BussinessException("参数错误");
            }
        }
        topicVote.setEndDate(DateUtil.parse(topicVote.getEndDateString(), DateTimePatternEnum.YYYY_MM_DD.getPattern()));
        this.cxyTopicVoteDao.insert(topicVote);
        List<CxyTopicVoteDetail> topicVoteDetails = new ArrayList<>();
        for (String title : voteTitle) {
            CxyTopicVoteDetail topicVoteDetail = new CxyTopicVoteDetail();
            topicVoteDetail.setTitle(title);
            topicVoteDetail.setVoteId(topicVote.getVoteId());
            topicVoteDetails.add(topicVoteDetail);
        }
        return this.topicVoteDetailDao.insertBatch(topicVoteDetails);
    }


    @Override
    public CxyTopicVote getTopicVote(Integer topicId, Integer userId) {
        if(topicId == null){
            return null;
        }
        CxyTopicVote topicVote = this.cxyTopicVoteDao.selectVoteByTopicId(topicId);
        boolean canVote = true;
        if(userId != null){
            TopicVoteUserQuery topicVoteUserQuery = new TopicVoteUserQuery();
            topicVoteUserQuery.setUserId(userId);
            topicVoteUserQuery.setVoteId(topicVote.getVoteId());
            List<CxyTopicVoteUser> list = this.topicVoteUserDao.selectList(topicVoteUserQuery);
            topicVote.setTopicVoteUserList(list);
            if(!list.isEmpty() || DateUtil.daysBetween(new Date(), topicVote.getEndDate()) < 0){
                canVote = false;
            }
        }
        List<CxyTopicVoteDetail> topicVoteDetailList = topicVote.getTopicVoteDetailList();
        int sumCount = 0;
        for(CxyTopicVoteDetail topicVoteDetail : topicVoteDetailList){
            sumCount = sumCount + topicVoteDetail.getCount();
        }
        topicVote.setSumCount(sumCount);
        topicVote.setCanVote(canVote);
        return topicVote;
    }

    @Override
    @Transactional(propagation= Propagation.REQUIRES_NEW, rollbackFor=BussinessException.class)
    public CxyTopicVote doVote(Integer voteId, Integer voteType,
                            Integer[] voteDetailId, Integer userId, Integer topicId) throws BussinessException {
        if(voteId == null || VoteType.getVoteTypeByValue(voteType) == null ||
                voteDetailId == null ||(VoteType.getVoteTypeByValue(voteId) == VoteType.SingleSelection &&
                voteDetailId.length > 1)){
            throw new BussinessException("参数错误");
        }
        TopicVoteUserQuery topicVoteUserQuery = new TopicVoteUserQuery();
        topicVoteUserQuery.setUserId(userId);
        topicVoteUserQuery.setVoteId(voteId);
        List<CxyTopicVoteUser> topicVoteUserList = this.topicVoteUserDao.selectList(topicVoteUserQuery);
        if(!topicVoteUserList.isEmpty()){
            throw new BussinessException("您已经投过票了");
        }
        Date curDate = new Date();
        CxyTopicVote topicVote = this.cxyTopicVoteDao.selectVoteByTopicId(topicId);
        if(topicVote == null){
            throw new BussinessException("投票不存在");
        }
        if(DateUtil.daysBetween(curDate, topicVote.getEndDate()) < 0){
            throw new BussinessException("投票已截止");
        }
        List<CxyTopicVoteUser> list = new ArrayList<>();
        List<Integer> voteDetailList = new ArrayList<>();
        for(Integer detailId : voteDetailId){
            CxyTopicVoteUser voteUser = new CxyTopicVoteUser();
            voteUser.setUserId(userId);
            voteUser.setVoteDate(Instant.now());
            voteUser.setVoteDetailId(detailId);
            list.add(voteUser);
            voteDetailList.add(detailId);
        }
        this.topicVoteUserDao.insertBatch(list);
        this.topicVoteDetailDao.updateVoteCountBatch(voteDetailList);
        return getTopicVote(topicId, userId);
    }

}